#include "inc/hw_memmap.h"
#include "gpio.h"
#include "LED.h"
#include "Button.h"

#define BUTTON_MASK (GPIO_PIN1 | GPIO_PIN2 | GPIO_PIN3 | GPIO_PIN4 | GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7)
#define BUTTON_PORT GPIO_PORT_P2

struct evtArr_s btnEvents;//  = {0};
//struct btn_debounce ACK = {0}, RESET = {0}, LAMP = {0};
struct btn_debounce btnStruct[eNumEvents];


//unsigned char SI_ackBtnLogic(void);
static unsigned char btnTurn = 0;
//static unsigned char speed = RATE_FAST;


unsigned short Button_get(unsigned char mask);

void BTN_initTrad(void)
{
	P2SEL &= ~BUTTON_MASK; // set to io
	P2DIR &= ~BUTTON_MASK; // set to input
	P2REN |= BUTTON_MASK; // enable pull up/down
	P2OUT |= BUTTON_MASK; // set to pull up


//	BUTTON_PORT = BUTTON_MASK;
//	GPIO_setAsInputPin(BUTTON_PORT, BUTTON_MASK);//BUTTON_MASK);
//	GPIO_setAsInputPinWithPullDownresistor(GPIO_PORT_P2, GPIO_PIN1);//BUTTON_MASK);
//	GPIO_setAsInputPinWithPullUpresistor(BUTTON_PORT, BUTTON_MASK);
}
unsigned short Button_getTrad(unsigned char mask)
{
	unsigned short result = 0;
	if (P2IN&mask)
	{
		result = 1;
	}
	__no_operation();
	return  result;//GPIO_getInputPinValue(BUTTON_PORT, mask);
}
void BTN_initMSPWare(void)
{
	GPIO_setAsInputPin(BUTTON_PORT, BUTTON_MASK);//BUTTON_MASK);
//	GPIO_setAsInputPinWithPullDownresistor(GPIO_PORT_P2, GPIO_PIN1);//BUTTON_MASK);
	GPIO_setAsInputPinWithPullUpresistor(BUTTON_PORT, BUTTON_MASK);
}
unsigned short Button_getMSPWare(unsigned char mask)
{
	return  GPIO_getInputPinValue(BUTTON_PORT, mask);
}

void BTN_init(void)
{
#if BTN_MSPWARE
	BTN_initMSPWare();
#else
	BTN_initTrad();
#endif
}
unsigned short Button_get(unsigned char mask)
{
	unsigned short result = 0;
#if BTN_MSPWARE
	result = Button_getMSPWare(mask);
#else
	result = Button_getTrad(mask);
#endif
	return  result;
}
void Button_test(void)
{
	BTN_init();

	GPIO_getInputPinValue(BUTTON_PORT, BTN_LAMP_TEST);

	GPIO_getInputPinValue(BUTTON_PORT, BTN_LAMP_TEST);
}
void btn_debounce_reset(struct btn_debounce *btn)
{
	btn->unpressed_cnt = 0;
	btn->pressed_cnt = 0;
	if (btn->eventCounts < (21845)) // prevent overflow
	{
		btn->lockout_cnt = btn->eventCounts*3;
	}
	else
	{
		btn->lockout_cnt = 65535;
	}
	btn->last = 1;
	btn->newTurn = 0;
	btn->event = 0;
	btn->current = 0;
}
void BTN_btnDebounce_init(/*struct btn_debounce *btn, */unsigned char mask, unsigned int eventCounts, enum evt_e event)
{
	struct btn_debounce *btn = btnEvents.evt[event].btn;
	btn_debounce_reset(btn);
	btn->mask = mask;
	btn->eventCounts = eventCounts;
	btn->lockout_cnt = 0;
	btnEvents.evt[event].btn = &btnStruct[event];//btn;
	btnEvents.evt[event].evtData = evt_no;
}

void BTN_debug(enum RATES rate)
{
#if BTN_DEBUG
	static enum RATES myRate;
	static unsigned char process = 0;
	if (rate == RATE_FAST)
	{
		process = 1;
	}
	if (rate == RATE_SLOW)
	{
		process = 0;
	}
	if (process)
	{
		if (myRate == RATE_ON)
		{

		}
		else
		{
			myRate = rate;
		}
	}
	else
	{
		myRate = RATE_OFF;
	}

	LED_setRate(LED_WARNING, myRate);
#endif
}
unsigned char event_btn_debounce(struct btn_debounce *btn)
{
//	static unsigned char newTurn = 0;
	btn->current = Button_get(btn->mask);
//	btn->event = 0;

	// pressed: 0
	// unpressed: 1
	// unpressed to pressed: 1 to 0
	// pressed to unpressed: 0 to 1
	if (btn->newTurn == btnTurn)
		return btn->event;
	btn->newTurn = btnTurn;
	if (btn->lockout_cnt)
	{
		btn->lockout_cnt--;
		return 0;
	}
	if (btn->current != btn->last)
	{
		btn->unpressed_cnt = 0;
		btn->pressed_cnt = 0;
	}
	else
	{
		if (btn->current == 1)
		{
			if (btn->unpressed_cnt < 65535)
			{
				btn->unpressed_cnt++;
				BTN_debug(RATE_OFF);
			}
		}
		else
		{
			if (btn->pressed_cnt < 65535)
			{
				btn->pressed_cnt++;
				BTN_debug(RATE_ON);
			}
		}
	}
//	btn->event = 0;
	if (btn->pressed_cnt == btn->eventCounts)//2)
	{
		btn->event = 1;
	}
	btn->last = btn->current;
	return btn->event;
}
#if TEST_SI
void Buttons_check(void)
{
	if (!Button_get(BTN_WARNING))
	{
		speed = RATE_SLOW_SLOW;
	}
	if (!Button_get(BTN_LAMP_TEST))
	{
		speed = RATE_SLOW;
	}
	if (!Button_get(BTN_RESET))
	{
		speed = RATE_FAST;
	}
	if (!Button_get(BTN_GA_ON))
	{
		speed = RATE_ON;
	}
	if (!Button_get(BTN_GA_OFF))
	{
		speed = RATE_OFF;
	}

}
#endif
//event[eBtnReset].evt = 0;
//event[eBtnReset].evtMsg[0] = 0;

void BTN_btnEvent_init(void)
{
	BTN_btnEvent_clearAckReset();
}
void BTN_btnEvent_process(void)
{
	BTN_debug(RATE_FAST);
	btnEvents.evt[eBtnReset].evtData = (enum EvtState)event_btn_debounce(btnEvents.evt[eBtnReset].btn); //&RESET);
	btnEvents.evt[eBtnAck].evtData = (enum EvtState)event_btn_debounce(btnEvents.evt[eBtnAck].btn); //&ACK); // SI_ackBtnLogic();
	btnEvents.evt[eBtnLampTest].evtData = (enum EvtState)event_btn_debounce(btnEvents.evt[eBtnLampTest].btn); //&LAMP); // SI_ackBtnLogic();
	btnEvents.evt[eBtnSvcMode].evtData = (enum EvtState)event_btn_debounce(btnEvents.evt[eBtnSvcMode].btn); //&LAMP); // SI_ackBtnLogic();
	btnEvents.evt[eBtnGAoff].evtData = (enum EvtState)event_btn_debounce(btnEvents.evt[eBtnGAoff].btn); //&LAMP); // SI_ackBtnLogic();
	btnEvents.evt[eBtnGAon].evtData = (enum EvtState)event_btn_debounce(btnEvents.evt[eBtnGAon].btn); //&LAMP); // SI_ackBtnLogic();
	btnEvents.evt[eBtnWarning].evtData = (enum EvtState)event_btn_debounce(btnEvents.evt[eBtnWarning].btn); //&LAMP); // SI_ackBtnLogic();
	BTN_debug(RATE_SLOW);
}
void BTN_btnEvent_testSet(enum evt_e evt, enum EvtState state)
{
	btnEvents.evt[evt].evtData = state;
}
enum EvtState BTN_btnEvent_get(enum evt_e evt)
{
	return btnEvents.evt[evt].evtData;
}
void BTN_btnEvent_consume(enum evt_e evt)
{
	if (btnEvents.evt[evt].evtData == evt_yes)
	{
		btn_debounce_reset(btnEvents.evt[evt].btn);
		btnEvents.evt[evt].evtData = evt_no;
	}
}
void BTN_btnEvent_clearGAbtns(void)
{
	BTN_btnEvent_consume(eBtnGAoff);
	BTN_btnEvent_consume(eBtnGAon);
}
void BTN_btnEvent_clearAckReset(void)
{
//	enum evt_e i;
//	for (i=(enum evt_e)0; i<eNumEvents; i++)
//		BTN_btnEvent_consume(i);
	BTN_btnEvent_consume(eBtnReset);
	BTN_btnEvent_consume(eBtnAck);
}
void SI_updateBtnTimer(void)
{
	btnTurn++;
}
/*
unsigned char SI_ackBtnLogic(void)
{
	enum LED_INDEX i;
	unsigned char consumed = 0;
	unsigned char stillBlinking = 0;
	unsigned char consumedBy = 10;

	if(	event_btn_debounce(&ACK))
	{
 		for (i=LED_SI_1_Alm; i<=LED_SI_8_Flt; i++)
		//for (i=LED_SI_3_Alm; i<=LED_SI_8_Alm; i++)
		{
			if (LED_getRate(i) > RATE_ON)
			{
				consumed = 1;
				stillBlinking++;
				consumedBy = i;
				LED_setRate(i, RATE_ON);//LED_Rate[i] = RATE_ON;
				break;
			}
		}
		if (!consumed)
		{
			for (i=LED_SI_1_Flt; i<=LED_SI_8_Flt; i++)
			{
				if (LED_getRate(i) > RATE_ON)
				{
					consumed = 1;
					stillBlinking++;
					consumedBy = i;
					LED_setRate(i, RATE_ON);//LED_Rate[i] = RATE_ON;
					break;
				}
			}
		}
	}
	return consumedBy;
}
*/
